package me.szlx.thing.manager;

import me.szlx.thing.Thing;
import me.szlx.thing.ThingException;
import me.szlx.thing.Trait;
import me.szlx.thing.TraitLet;
import me.szlx.thing.bundle.ThingBundle;

import java.util.*;
import java.util.stream.Collectors;

public abstract class AbstractThingManager<T extends Thing> implements ThingManager<T> {
    @Override
    public T get(Object id) {
        Optional<T> thing = getThingList().stream().filter(t -> t.getId() == id).findFirst();
        if (!thing.isPresent()) {
            throw new ThingException("指定的事物不存在：" + String.valueOf(id));
        }
        return thing.get();
    }

    @Override
    public List<T> list(TraitLet... filters) {
        return getThingList().stream().filter(t -> t.match(filters)).collect(Collectors.toList());
    }

    @Override
    public Map<String, List<T>> group(String tagName, TraitLet... filters) {
        Objects.requireNonNull(tagName, "特性的名称不能为null");
        Map<String, List<T>> result = new HashMap<>();
        list(filters).forEach(thing -> {
            Trait trait = thing.getTraits().ofName(tagName);
            if (trait != null) {
                String label = trait.getValue();
                List<T> theLableThingList = result.get(label);
                if (theLableThingList == null) {
                    theLableThingList = new ArrayList<>();
                }
                theLableThingList.add(thing);
            }
        });
        return result;
    }

    private List<T> getThingList() {
        ThingBundle<T> bundle = getThingBundle();
        return bundle != null ? bundle.getAll() : new ArrayList<>();
    }

    /**
     * 返回全部的事物对象列表。如果没有任何事物对象，则返回空的列表。
     *
     * @return 全部的事物对象列表。如果没有任何事物对象，则返回空的列表。
     */
    protected abstract ThingBundle<T> getThingBundle();
}
